
using CefSharp;
using CefSharp.WinForms;
using NativeInterop; // 委托集中管理类，预定义了许多委托类型方便在函数中使用
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.ComponentModel;
using System.Data;
using System.Data.SQLite;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Reflection.Metadata;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using static NativeInterop.Kernel32;
using static System.Net.Mime.MediaTypeNames;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;

namespace 哇哦软件开发
{

    public partial class Form1 : Form
    {
        //浏览器控件初始化
        public ChromiumWebBrowser browser = new ChromiumWebBrowser("file:///./src/index.html");
        //一个新的浏览器控件
        public static ChromiumWebBrowser hiddenBrowser = new ChromiumWebBrowser();

        
        public Form1()
        {
            hiddenBrowser.Width = 0;
            hiddenBrowser.Height = 0;
            hiddenBrowser.Visible = true; //如果是 false 则隐藏
            this.Controls.Add(hiddenBrowser);
            //窗体初始化
            InitializeComponent();
            //浏览器初始化
            InitializeBrowser();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

           
            
        }


        private void InitializeBrowser()
        {
           // browser.JavascriptObjectRepository.Settings.LegacyBindingEnabled = true;

            browser.JavascriptObjectRepository.Register("bound", new BoundApi());
            //将浏览器控件添加到窗体 DockStyle.Fill 自动填充
            browser.Dock = DockStyle.Fill;
            this.Controls.Add(browser);

            browser.KeyboardHandler = new CustomKeyboardHandler();
            // 初始化浏览器控件时添加事件监听
            browser.TitleChanged += (sender, args) =>
            {
                // 跨线程安全更新UI
                this.Invoke((System.Windows.Forms.MethodInvoker)delegate
                {
                    this.Text = args.Title; // 将窗体标题同步为浏览器标题
                });
            };
        }
    }

    public class BoundApi
    {
        //请求网页
        public async Task<string> Webdata(string url)
        {
            Debug.WriteLine($"hello Webdata");
            var tcs = new TaskCompletionSource<string>();
            Form1.hiddenBrowser.Load(url);
            Form1.hiddenBrowser.FrameLoadEnd += async (sender, args) => {
                Debug.WriteLine($"hello Webdata 2");
                if (args.Frame.IsMain)
                {
                    var jsResult = await args.Frame.EvaluateScriptAsync(
                        "document.documentElement.outerHTML");
                    tcs.TrySetResult(jsResult.Result.ToString());
                }
            };




            Debug.WriteLine($"hello Webdata 3");
            return await tcs.Task;
        }



        //动态查找委托类型
        public static Type FindDelegateType(string dllPath, string delegateName)
        {
            // 获取NativeDelegates类的所有嵌套类型
            if(dllPath == "kernel32.dll")
            {
                Type[] nestedTypes = typeof(Kernel32).GetNestedTypes();
                foreach (Type type in nestedTypes)
                {
                    // 检查类型是否是委托且名称匹配
                    if (type.IsSubclassOf(typeof(Delegate)) && type.Name == delegateName)
                    {
                        return type;
                    }
                }
            }
            if (dllPath == "Shell32.dll")
            {
                Type[] nestedTypes = typeof(Shell32).GetNestedTypes();
                foreach (Type type in nestedTypes)
                {
                    // 检查类型是否是委托且名称匹配
                    if (type.IsSubclassOf(typeof(Delegate)) && type.Name == delegateName)
                    {
                        return type;
                    }
                }
            }
            return null;
        }
        //委托调用方法 Delegate call method
        public object Hello(string dllPath, string funcName, string args, string types, IJavascriptCallback callback)
        {
            

            IntPtr hModule = IntPtr.Zero;
            try
            {
                Debug.WriteLine($"hello {funcName}");
                // 1. 动态查找委托类型
                Type delegateType = FindDelegateType(dllPath, funcName);
                if (delegateType == null) throw new Exception("Delegate not found");
                Debug.WriteLine($"world");
                // 2. 加载API并创建委托
                hModule = LoadLibrary(dllPath);
                IntPtr procAddress = GetProcAddress(hModule, funcName);

                var delegateInstance = Marshal.GetDelegateForFunctionPointer(
                    procAddress, delegateType);

                // 解析JSON字符串到字典
                var paramsMapping = JsonConvert.DeserializeObject<Dictionary<string, object>>(args);
                var typeMapping = JsonConvert.DeserializeObject<Dictionary<string, string>>(types);

                // 3. 安全调用 需要每个方法都设置
                switch (funcName)
                {
                     case "GetSystemDirectoryW":
                        if (delegateInstance is Kernel32.GetSystemDirectoryW GetSystemDirectoryW)
                        {
                            var buffer = new StringBuilder(Convert.ToInt32(paramsMapping["lpBuffer"]));
                            uint usize = Convert.ToUInt32(paramsMapping["uSize"]);
                            var result = GetSystemDirectoryW(buffer, usize);
                            Debug.WriteLine($"System Directory: {buffer}");
                            var data = new { SystemPath = buffer.ToString() };
                            callback.ExecuteAsync(JsonConvert.SerializeObject(data));
                            //如果不带 .ToString() 的话则返回 {"m_MaxCapacity":2147483647,"Capacity":260,"m_StringValue":"C:\\Windows\\system32","m_currentThread":0} 全部对象
                            return result;
                        }
                        break;
                    case "GetSystemInfo":
                        if (delegateInstance is Kernel32.GetSystemInfo GetSystemInfo)
                        {
                            Kernel32.SYSTEM_INFO lpSystemInfo;
                            GetSystemInfo(out lpSystemInfo);
                            Debug.WriteLine($"System Directory: {lpSystemInfo}");
                            callback.ExecuteAsync(JsonConvert.SerializeObject(lpSystemInfo));

                            return 1;
                        }
                        break;
                    case "GlobalMemoryStatusEx":
                        if (delegateInstance is Kernel32.GlobalMemoryStatusEx GlobalMemoryStatusEx)
                        {
                            Kernel32.MEMORYSTATUSEX lpBuffer;
                            MEMORYSTATUSEX memStatus = new Kernel32.MEMORYSTATUSEX();
                            lpBuffer.dwLength = (uint)Marshal.SizeOf(memStatus); // 必须初始化结构体大小
                            GlobalMemoryStatusEx(out lpBuffer);
                            Debug.WriteLine($"System Directory: {lpBuffer}");
                            callback.ExecuteAsync(JsonConvert.SerializeObject(lpBuffer));

                            return 1;
                        }
                        break;
                    case "SHGetFolderPathW": //获得系统文件路径
                        if (delegateInstance is Shell32.SHGetFolderPathW SHGetFolderPathW)
                        {
                            IntPtr hwndOwner = IntPtr.Zero; //保留
                            int nFolder = Convert.ToInt32(paramsMapping["nFolder"]);
                            IntPtr hToken = Convert.ToInt32(paramsMapping["hToken"]);
                            uint dwFlags = Convert.ToUInt32(paramsMapping["dwFlags"]);

                            var desktopPath = new StringBuilder(256);
                            

                            SHGetFolderPathW(hwndOwner, nFolder, hToken, dwFlags, desktopPath);
                            Debug.WriteLine($"desktopPath: {desktopPath}");
                            var data = new { desktopPath = desktopPath.ToString() };
                            callback.ExecuteAsync(JsonConvert.SerializeObject(data));

                            return 1;
                        }
                        break;
                    case "CreateDirectoryW": //创建文件夹
                        if (delegateInstance is Kernel32.CreateDirectoryW CreateDirectoryW) {
                            var lpPathnName = new StringBuilder(Convert.ToInt32(paramsMapping["lpBuffer"]));

                            Kernel32.SECURITY_ATTRIBUTES lpSecurityAttributes = new Kernel32.SECURITY_ATTRIBUTES();
                            lpSecurityAttributes.nLength = (uint)Marshal.SizeOf(typeof(Kernel32.SECURITY_ATTRIBUTES));

                            bool result = CreateDirectoryW(lpPathnName, IntPtr.Zero);
                        }
                        break;
                     
                        
                    // 其他类型处理...
                    default:
                    throw new NotSupportedException($"Unsupported type: {funcName}");
                }
                
               
                return -1;
            }
            finally
            {
                if (hModule != IntPtr.Zero)
                    FreeLibrary(hModule);
            }
        }

        public string showNotification(string msg)
        {
            Debug.WriteLine($"JS调用收到: {msg}");
            return "JS调用收到: {msg}";
        }

        
        //JS调用dll方法
        // 非托管DLL动态调用

        [DllImport("kernel32.dll")]
        private static extern IntPtr LoadLibrary(string dllName);

        [DllImport("kernel32.dll")]
        private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

        [DllImport("kernel32.dll")]
        private static extern bool FreeLibrary(IntPtr hModule);
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern uint GetLastError();
        //关闭句柄
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool CloseHandle(IntPtr hObject);

        public object InvokeUnmanagedMethod(
        string dllPath,
        string funcName,
        string paramsDict,
        string argTypes)
        {
            Debug.WriteLine("begining====================================");
            Debug.WriteLine("调用dll: " + dllPath);
            Debug.WriteLine("调用方法：" + funcName);
            Debug.WriteLine("调用参数：" + paramsDict);
            Debug.WriteLine("调用参数类型： " + argTypes);
            //paramsMapping paramsDict {"hWnd":0,"text":"操作成功","caption":"系统提示","type":64}
            //typeMapping argTypes {"hWnd":"System.IntPtr","text":"System.String","caption":"System.String","type":"System.UInt32"}
            IntPtr hModule = LoadLibrary(dllPath); //user32.dll
            if (hModule == IntPtr.Zero)
                Debug.WriteLine($"DLL加载失败 (0x{Marshal.GetLastWin32Error():X8})");
            Debug.WriteLine($"DLL加载成功");
            try
            {
                // 解析JSON字符串到字典
                var paramsMapping = JsonConvert.DeserializeObject<Dictionary<string, object>>(paramsDict);
                var typeMapping = JsonConvert.DeserializeObject<Dictionary<string, string>>(argTypes);
                Debug.WriteLine($"测试1");
                // 设置 定义Invoke方法签名 的第四个参数，类型为 Type[]数组
                Type[] paramTypes = typeMapping.Values
            .Select(typeName => Type.GetType(typeName) ??
                throw new ArgumentException($"无法解析类型: {typeName}"))
            .Where(type => type != null)
            .ToArray();
                Debug.WriteLine($"测试2");
                Debug.WriteLine(string.Join(", ", paramTypes.Select(t => t.FullName)));


                //Type[] paramTypes = new Type[] {typeof(System.IntPtr),typeof(System.String),typeof(System.String),typeof(System.UInt32)};
                var delegateType = CreateMessageBoxDelegateType(paramTypes);
                Debug.WriteLine($"动态生成的委托类型: {delegateType.FullName}");
                Debug.WriteLine($"委托类型: {delegateType.Name}");
                MethodInfo method = delegateType.GetMethod("Invoke");
                Debug.WriteLine($"返回类型: {method.ReturnType.Name}");
                Debug.WriteLine("参数类型:");
                foreach (ParameterInfo param in method.GetParameters())
                {
                    Debug.WriteLine($"- {param.ParameterType.Name}");
                }

                Debug.WriteLine($"特性检查: {delegateType.GetCustomAttribute<UnmanagedFunctionPointerAttribute>() != null}");

                IntPtr proc = GetProcAddress(hModule, funcName); //messageBoxW
                Debug.WriteLine($"funcName: {funcName}");
                if (proc == IntPtr.Zero) throw new EntryPointNotFoundException();
                Debug.WriteLine($"proc: {proc}");
                // 正确转换方式
                //delegateType定义为delegate void Handler(int, string) 则委托的方法参数需要一致
                var function_name = (dynamic)Marshal.GetDelegateForFunctionPointer(proc, delegateType);
                if (paramsMapping.Count == 4) {
                    
                }
                object[] args = new object[paramsMapping.Count];
                // 直接按顺序填充参数值
                Debug.WriteLine($"请求参数解析：");
                Debug.WriteLine($"参数长度： {paramsMapping.Count}");
                for (int i = 0; i < paramsMapping.Count; i++)
                {
                    var paramKey = paramsMapping.ElementAt(i).Key;
                    var paramValue = paramsMapping.ElementAt(i).Value;

                    // 从 typeMapping 获取参数类型
                    if (typeMapping.TryGetValue(paramKey, out string typeName))
                    {
                        Debug.WriteLine($"ok: {typeName}  {paramValue}");
                        // 根据类型名称转换参数值
                        switch (typeName)
                        {
                           
                            case "System.IntPtr":
                                args[i] = (IntPtr)Convert.ToInt64(paramValue); // 若为 null 则赋值为 IntPtr.Zero
                                break;
                            case "System.String":
                                args[i] = paramValue?.ToString(); // 若为 null 则赋值为 null
                                break;
                            case "System.UInt32":
                                args[i] = Convert.ToUInt32(paramValue); // 若为 null 则赋值为 null
                                break;
                            case "SYSTEM_INFO":
                                args[i] = JsonConvert.DeserializeObject<SYSTEM_INFO>(paramValue.ToString());
                                break;
                            // 其他类型处理...
                            default:
                                throw new NotSupportedException($"Unsupported type: {typeName}");
                        }
                    }
                    else
                    {
                        throw new KeyNotFoundException($"Type mapping not found for key: {paramKey}");
                    }
                }

                // 调用方法 - 值返回
                Debug.WriteLine($"args: {args}");
                var result = function_name.DynamicInvoke(args);
                uint data = GetLastError();
                Debug.WriteLine(data);
                Debug.WriteLine($"result: {result} {GetLastError()}");
                if (result != null)
                {
                    Debug.WriteLine($"返回值类型：{result.GetType()}");
                    //文件句柄释放有点问题
                    if (CloseHandle((IntPtr)result))
                    {
                        Debug.WriteLine($"释放可文件句柄");
                    }
                    else
                    {
                        Debug.WriteLine($"释放文件句柄失败");
                    }
                }
                else
                {
                    Debug.WriteLine("返回值为null");
                }

                return result;
                //messageBox(IntPtr.Zero, "hello", "动态调用222", 0x00000040);

            }
            catch {
                
            }
            finally
            {
                FreeLibrary(hModule);
            }

                return -1;
        }

        // 反射动态调用方法
        public static Type CreateMessageBoxDelegateType(Type[] paramTypes)
        {
            // 创建动态程序集和模块
            var assemblyName = new AssemblyName("DynamicDelegates");
            var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            var moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
            Debug.WriteLine($"111");
            // 定义委托类型
            var typeBuilder = moduleBuilder.DefineType(
                "DynamicMessageBoxDelegate",
                TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.AutoClass,
                typeof(MulticastDelegate));
            Debug.WriteLine($"222");
            // 添加构造函数和Invoke方法
            var ctorBuilder = typeBuilder.DefineConstructor(
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                CallingConventions.Standard,
                new[] { typeof(object), typeof(IntPtr) });
            ctorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);
            Debug.WriteLine($"333");
            // 定义Invoke方法签名
            var methodBuilder = typeBuilder.DefineMethod(
                "Invoke",
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual,
                typeof(int),
                paramTypes);
            methodBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);
            Debug.WriteLine($"444");
            // 添加UnmanagedFunctionPointer特性
            var attributeCtor = typeof(UnmanagedFunctionPointerAttribute).GetConstructor(new[] { typeof(CallingConvention) });
            var charSetField = typeof(UnmanagedFunctionPointerAttribute).GetField("CharSet");
            var attributeBuilder = new CustomAttributeBuilder(
                attributeCtor,
                new object[] { CallingConvention.StdCall },
                new[] { charSetField },
                new object[] { CharSet.Unicode });
            typeBuilder.SetCustomAttribute(attributeBuilder);
            Debug.WriteLine($"555");
            // 创建委托类型
            return typeBuilder.CreateType();
        }


        //数据库操作
        public object sqlite(string tablename, string sql, string paramsDict)
        {
            //CREATE 创建数据表
            if (sql.StartsWith("CREATE"))
            {
                using (var connection = new SQLiteConnection("Data Source=" + tablename))
                {
                    connection.Open();

                    using (var command = connection.CreateCommand())
                    {
                        command.CommandText = sql;
                        int rowsAffected = command.ExecuteNonQuery();
                        Debug.WriteLine("已经创建了表");
                        Debug.WriteLine($"创建了 {rowsAffected} 条记录");
                        var data = new { result = rowsAffected.ToString() };
                        return JsonConvert.SerializeObject(data);
                    }

                }
            }
            //SELECT 查询表
            if (sql.StartsWith("SELECT"))
            {
                using (var connection = new SQLiteConnection("Data Source=" + tablename))
                {
                    connection.Open();
                    using (var command = connection.CreateCommand())
                    {
                        command.CommandText = sql;
                        // 解析JSON字符串到字典
                        var paramsMapping = JsonConvert.DeserializeObject<Dictionary<string, object>>(paramsDict);
                        if (paramsMapping.Count > 0)
                        {
                            foreach (var kvp in paramsMapping)
                            {
                                string key = kvp.Key;
                                object value = kvp.Value;
                                command.Parameters.AddWithValue("@" + key, value);
                            }
                            Debug.WriteLine("存在参数");
                        }
                        else {
                            Debug.WriteLine("没有参数");
                        }
                            using (var reader = command.ExecuteReader())
                            {
                                Debug.WriteLine("===================================");
                            Debug.WriteLine("结果:");
                            //创建一个列表来存储所有行的数据
                            var dataList = new List<Dictionary<string, object>>();
                                while (reader.Read())
                                {
                                    //创建一个字典来存储每一行的数据，每行数据包含 WindowName, ProcessName, Data
                                    //然后将字典添加到列表中
                                    var record = new Dictionary<string, object>();

                                    // 动态添加所有字段
                                    for (int i = 0; i < reader.FieldCount; i++)
                                    {
                                        string fieldName = reader.GetName(i);
                                        record[fieldName] = reader.GetValue(i);
                                    }
                                    dataList.Add(record);
                                }

                            string jsonResult = JsonConvert.SerializeObject(dataList);
                            Console.WriteLine(jsonResult); // 控制台输出
                            Debug.WriteLine("===================================");
                                return JsonConvert.SerializeObject(dataList);
                            }
                    }
                }
            }
            //INSERT 添加数据
            if (sql.StartsWith("INSERT"))
            {
                using (var connection = new SQLiteConnection("Data Source=" + tablename))
                {
                    connection.Open();

                    using (var command = connection.CreateCommand())
                    {
                        command.CommandText = sql;
                        // 解析JSON字符串到字典
                        var paramsMapping = JsonConvert.DeserializeObject<Dictionary<string, object>>(paramsDict);
                        foreach (var kvp in paramsMapping)
                        {
                            string key = kvp.Key;
                            object value = kvp.Value;
                            command.Parameters.AddWithValue("@" + key, value);
                        }
                        int affectedRows = command.ExecuteNonQuery();
                        Debug.WriteLine($"已插入{affectedRows}条记录");
                        var data = new { result = affectedRows.ToString() };
                        return JsonConvert.SerializeObject(data);
                    }

                }
            }
            //DROP 删除表
            if (sql.StartsWith("DROP"))
            {
                using (var connection = new SQLiteConnection("Data Source=" + tablename))
                {
                    connection.Open();

                    // 执行删除表操作
                    using (var command = connection.CreateCommand())
                    {
                        command.CommandText = sql;
                        int rowsAffected = command.ExecuteNonQuery();
                        Debug.WriteLine($"删除了 {rowsAffected} 个数据表");
                        Debug.WriteLine(rowsAffected);
                        var data = new { result = rowsAffected.ToString() };
                        return JsonConvert.SerializeObject(data);
                    }
                }
            }
            //DELETE 删除数据
            if (sql.StartsWith("DELETE"))
            {
                using (var connection = new SQLiteConnection("Data Source=" + tablename))
                {
                    connection.Open();
                    // 执行删除表操作
                    using (var command = connection.CreateCommand())
                    {
                        command.CommandText = sql;
                        // 解析JSON字符串到字典
                        var paramsMapping = JsonConvert.DeserializeObject<Dictionary<string, object>>(paramsDict);
                        foreach (var kvp in paramsMapping)
                        {
                            string key = kvp.Key;
                            object value = kvp.Value;
                            command.Parameters.AddWithValue("@" + key, value);
                        }
                        int rowsAffected = command.ExecuteNonQuery();
                        Debug.WriteLine($"删除了 {rowsAffected} 条记录");
                        var data = new { result = rowsAffected.ToString() };
                        return JsonConvert.SerializeObject(data);
                    }

                }
            }
            //DELETE 更新数据
            if (sql.StartsWith("UPDATE"))
            {
                using (var connection = new SQLiteConnection("Data Source=" + tablename))
                {
                    connection.Open();
                    using (var command = connection.CreateCommand())
                    {
                        command.CommandText = sql;
                        // 解析JSON字符串到字典
                        var paramsMapping = JsonConvert.DeserializeObject<Dictionary<string, object>>(paramsDict);
                        foreach (var kvp in paramsMapping)
                        {
                            string key = kvp.Key;
                            object value = kvp.Value;
                            command.Parameters.AddWithValue("@" + key, value);
                        }
                        int rowsAffected = command.ExecuteNonQuery();
                        Debug.WriteLine($"修改了 {rowsAffected} 条记录");
                        var data = new { result = rowsAffected.ToString() };
                        return JsonConvert.SerializeObject(data);
                    }
                }
            }

            string json = JsonConvert.SerializeObject(""); // 序列化为JSON字符串
            return json;
        }
    }
    
}
